package com.ts.opengl.simpleDraw

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.opengl.GLES20
import android.opengl.GLES20.GL_COLOR_ATTACHMENT0
import android.opengl.GLES20.GL_FLOAT
import android.opengl.GLES20.GL_FRAMEBUFFER
import android.opengl.GLES20.GL_LINEAR
import android.opengl.GLES20.GL_NEAREST
import android.opengl.GLES20.GL_TEXTURE_2D
import android.opengl.GLES20.GL_TEXTURE_MAG_FILTER
import android.opengl.GLES20.GL_TEXTURE_MIN_FILTER
import android.opengl.GLES20.glBindFramebuffer
import android.opengl.GLES20.glBindTexture
import android.opengl.GLES20.glFramebufferTexture2D
import android.opengl.GLES20.glGenTextures
import android.opengl.GLES20.glGetError
import android.opengl.GLES20.glTexParameteri
import android.opengl.GLES20.glUseProgram
import android.opengl.GLES20.glVertexAttribPointer
import android.opengl.GLES30
import android.opengl.GLSurfaceView
import android.opengl.GLUtils
import android.util.Log
import com.ts.audiocamera.R
import com.ts.opengl.OpenGLUtils
import java.nio.IntBuffer
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10

class FBONewRender(var context:Context):GLSurfaceView.Renderer {
    var ver= floatArrayOf(
        // positions         //color              // texture coords
        -1.0f,  1.0f, 0.0f,   1.0f, 0.0f, 0.0f,    1.0f, 0.0f, // top right
        -1.0f, -1.0f, 0.0f,   1.0f, 0.0f, 1.0f,   1.0f, 1.0f, // bottom right
        1.0f, 1.0f, 0.0f,   1.0f, 0.0f, 1.0f,   0.0f,0.0f, // bottom left
        1.0f,  -1.0f, 0.0f,   0.0f, 0.5f, 1.0f,   0.0f, 1.0f, // top left
    )

    var ele= intArrayOf(
        0, 1, 2,
        1, 2, 3

    )

    val vbo=IntArray(1)
    val vao=IntArray(1)
    val ebo=IntArray(1)
    val texture=IntArray(2)
    lateinit var eleCor:IntBuffer
    private  val TAG = "FBONewRender"
    var program=0;
    var fboprogram=0;
    override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
        program=openglUtil.createProgram(context,R.raw.fbo_new_ver,R.raw.fbo_new_frag)
        fboprogram=openglUtil.createProgram(context,R.raw.fbo_new_ver,R.raw.fbo2_new_frag)
        val verCor=openglUtil.createFloatBuffer(ver)
        eleCor=openglUtil.createIntBuffer(ele)


        GLES30.glGenVertexArrays(vao.size,vao,0)

        GLES30.glGenBuffers(vbo.size,vbo,0)

        //正常渲染--------------------------------------------------------------
        GLES30.glBindVertexArray(vao[0])
        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,vbo[0])
        GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER,verCor.capacity()*4,verCor,
            GLES30.GL_STATIC_DRAW)
        Log.e(TAG, "onSurfaceCreated: "+glGetError().toString()+"")

        GLES30.glGenBuffers(ebo.size,ebo,0)
        GLES30.glBindBuffer(GLES30.GL_ELEMENT_ARRAY_BUFFER,ebo[0])
        GLES30.glBufferData(GLES30.GL_ELEMENT_ARRAY_BUFFER,eleCor.capacity()*4,
            eleCor,GLES30.GL_STATIC_DRAW)
        Log.e(TAG, "onSurfaceCreated: "+glGetError().toString()+"")
        verCor.position(0)
        GLES30.glVertexAttribPointer(0,3,GLES30.GL_FLOAT,false,
            8*4,0)
        GLES30.glEnableVertexAttribArray(0)

        verCor.position(3)
        GLES30.glVertexAttribPointer(1,3,GLES30.GL_FLOAT,false,
            8*4,3*4)
        GLES30.glEnableVertexAttribArray(1)

        verCor.position(6)
        GLES30.glVertexAttribPointer(2,2,GLES30.GL_FLOAT,false,
            8*4,6*4)

        GLES30.glEnableVertexAttribArray(2)

        GLES30.glBindVertexArray(0)
        GLES30.glBindBuffer(GLES30.GL_ELEMENT_ARRAY_BUFFER,0)
        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,0)



        //纹理  //创建纹理
        glGenTextures(texture.size,texture,0)
        glBindTexture(GL_TEXTURE_2D,texture[0])
        glTexParameteri(GLES30.GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
        glTexParameteri(GLES30.GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        //纹理过滤
        GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D,GLES30.GL_TEXTURE_MIN_FILTER,
            GLES30.GL_NEAREST)
        GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D,GLES30.GL_TEXTURE_MAG_FILTER
            ,GLES30.GL_LINEAR)
        val bitmap=BitmapFactory.decodeResource(context.resources,R.drawable.cdemo)
        GLUtils.texImage2D(GLES30.GL_TEXTURE_2D,0,bitmap,0)
        GLES30.glGenerateMipmap(GLES30.GL_TEXTURE_2D)
        glBindTexture(GL_TEXTURE_2D,0)



        createFob(bitmap)

        GLES30.glBindVertexArray(0)
        GLES30.glBindBuffer(GLES30.GL_ELEMENT_ARRAY_BUFFER,0)
        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,0)

    }
    val fbo=IntArray(1)
    private fun createFob(bitmap:Bitmap) {
        //创建并初始化 FBO 纹理

//        glGenTextures(fborexture.size,texture【】】,0)
        glBindTexture(GL_TEXTURE_2D,texture[1])
        glTexParameteri(GLES30.GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
        glTexParameteri(GLES30.GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        //纹理过滤
        GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D,GLES30.GL_TEXTURE_MIN_FILTER,
            GLES30.GL_NEAREST)
        GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D,GLES30.GL_TEXTURE_MAG_FILTER,GLES30.GL_LINEAR)



//        glBindTexture(GL_TEXTURE_2D,texture[2])
//        glTexParameteri(GLES30.GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
//        glTexParameteri(GLES30.GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
//        //纹理过滤
//        GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D,GLES30.GL_TEXTURE_MIN_FILTER,
//            GLES30.GL_NEAREST)
//        GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D,GLES30.GL_TEXTURE_MAG_FILTER,GLES30.GL_LINEAR)
//        glBindTexture(GL_TEXTURE_2D,0)

        //创建fbo

        GLES30.glGenFramebuffers(fbo.size,fbo,0)
        GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER,fbo[0])


        //创建fbo纹理

//        var bit=BitmapFactory.decodeResource(context.resources,R.drawable.hyw)
//        GLUtils.texImage2D(GL_TEXTURE_2D,0,bit,0)
        GLES30.glTexImage2D( GLES30.GL_TEXTURE_2D,
            0,
            GLES30.GL_RGB,
            bitmap.width,
            bitmap.height,
            0,
            GLES30.GL_RGB,
            GLES30.GL_UNSIGNED_SHORT_5_6_5,
            null)

          //绑定fbo
        glBindFramebuffer(GL_FRAMEBUFFER,fbo[0])
         //
        //绑定fbo 和纹理

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
            GL_TEXTURE_2D,
            texture[1],0)
        val status = GLES30.glCheckFramebufferStatus(GLES30.GL_FRAMEBUFFER)

        if (status != GLES30.GL_FRAMEBUFFER_COMPLETE) {
            throw RuntimeException("Failed to create texture.")
        }

        glBindTexture(GL_TEXTURE_2D,0)
        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, 0)
        GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, 0)
    }

    var width=0;
    var height=0;
    override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
        this.width=width;
        this.height=height;
        gl?.glViewport(0,0,width,height)
    }

    override fun onDrawFrame(gl: GL10?) {
        GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT)
        gl?.glViewport(0,0,width,height)
        glUseProgram(fboprogram)
        GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER,fbo[0])
        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D,texture[0])
        GLES30.glBindVertexArray(vao[0])

        GLES30.glDrawElements(GLES30.GL_TRIANGLE_STRIP, 6, GLES30.GL_UNSIGNED_INT, 0)

        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D,0)
        GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER,0)
        GLES30.glBindVertexArray(0)

        GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT)
        gl?.glViewport(0,0,width,height)
        glUseProgram(program)

        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D,texture[1])
        GLES30.glBindVertexArray(vao[0])
        GLES30.glDrawElements(GLES30.GL_TRIANGLE_STRIP, 6, GLES30.GL_UNSIGNED_INT, 0)

        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D,0)
        GLES30.glBindVertexArray(0)
    }
}